package com.woniu.common.util;

import cn.hutool.core.util.IdUtil;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.concurrent.TimeUnit;

/**
 * mq发送消息工具类
 *
 * @author Administrator
 */
public class SendMessageUtil {
    /**
     * 发送消息
     *
     * @param msg
     * @param exchange
     * @param routingKey
     * @param rabbitTemplate
     */
    public static void sendMsg(StringRedisTemplate redisTemplate, RabbitTemplate rabbitTemplate, String exchange, String routingKey, String msg, String appId) {
        Message message = new Message(msg.getBytes());

        CorrelationData correlationData = new CorrelationData();
        correlationData.setReturnedMessage(message);
        correlationData.getReturnedMessage().getMessageProperties().setReceivedExchange(exchange);
        correlationData.getReturnedMessage().getMessageProperties().setReceivedRoutingKey(routingKey);
        correlationData.getReturnedMessage().getMessageProperties().setAppId(appId);

        // 交换机到队列放的值，消费者需要拿到的值也在这放，后续才能拿到appId
        MessagePostProcessor messagePostProcessor = new MessagePostProcessor() {
            @Override
            public Message postProcessMessage(Message message) throws AmqpException {
                message.getMessageProperties().setAppId(appId);
                // 生成token保证消息幂等性
                String token = IdUtil.fastUUID();
                // 保存token到redis
                redisTemplate.opsForValue().set("message:" + token, token, 30, TimeUnit.MINUTES);
                // token传到消费者
                message.getMessageProperties().setMessageId(token);
                return message;
            }
        };

        rabbitTemplate.convertAndSend(exchange, routingKey, msg, messagePostProcessor, correlationData);
    }

    public static void sendMsg(StringRedisTemplate redisTemplate, RabbitTemplate rabbitTemplate, String exchange, String routingKey, String msg) {
        sendMsg(redisTemplate, rabbitTemplate, exchange, routingKey, msg, null);
    }
}
